﻿namespace MassTransitTest.SqlSugarCore
{
    /// <summary>
    /// 非线程安全
    /// 建议注册成InstancePerLifetimeScope
    /// </summary>
    public class DbContext : IDbContext
    {
        private Dictionary<string, IDbHelper> dbContexts = new Dictionary<string, IDbHelper>();
        private readonly IConnectStringConfig connectStringConfig;
        
        public DbContext(IConnectStringConfig connectStringConfig)
        {
            this.connectStringConfig = connectStringConfig;
        }

        public void BeginTrans(string connectionStringType, DbTypeEnum dbProviderType)
        {
            var context = GetDbContext(connectionStringType, dbProviderType);
            context.BeginTrans(null);
        }

        public void CommitTrans(string connectionStringType, DbTypeEnum dbProviderType)
        {
            var context = GetDbContext(connectionStringType, dbProviderType);
            context.Commit();
        }
        public bool IsTransOpen(string connectionStringType, DbTypeEnum dbProviderType)
        {
            var context = GetDbContext(connectionStringType, dbProviderType);
            return context.IsTransOpen();
        }

        public void RollBackTrans(string connectionStringType, DbTypeEnum dbProviderType)
        {
            var context = GetDbContext(connectionStringType, dbProviderType);
            context.Rollback();
        }

        public IDbHelper GetDbContext(string connectionStringType, DbTypeEnum dbProviderType)
        {
            var key = $"{connectionStringType}-{(int)dbProviderType}";
            if (dbContexts.ContainsKey(key))
            {
                return dbContexts[key];
            }
            lock (dbContexts)
            {
                if (dbContexts.ContainsKey(key))
                {
                    return dbContexts[key];
                }
                dbContexts.Add(key, CreateDbContext(connectionStringType, dbProviderType));
                return dbContexts[key];
            }
        }

        public IDbHelper GetDbContext(string connectionStringType, DbTypeEnum dbProviderType, string connectString)
        {
            var key = $"{connectionStringType}-{(int)dbProviderType}";
            if (dbContexts.ContainsKey(key))
            {
                return dbContexts[key];
            }
            lock (dbContexts)
            {
                if (dbContexts.ContainsKey(key))
                {
                    return dbContexts[key];
                }
                dbContexts.Add(key, new ContextBase(connectString, dbProviderType));
                return dbContexts[key];
            }
        }

        /// <summary>
        /// 创建数据库操作对象
        /// </summary>
        /// <returns></returns>
        private IDbHelper CreateDbContext(string connectionStringType, DbTypeEnum dbProviderType)
        {
            var connectString = connectStringConfig.GetDbConfigs(connectionStringType);
            return new ContextBase(connectString.ConnectString,dbProviderType,connectString.SlaveConfigs);
        }

        public void Dispose()
        {
            if (dbContexts != null && dbContexts.Count > 0)
            {
                foreach (var item in dbContexts)
                {
                    item.Value.Dispose();
                }
                dbContexts.Clear();
            }
        }

        ~DbContext()
        {
            Dispose();
        }
    }

    /// <summary>
    /// 非线程安全
    /// 建议注册成InstancePerLifetimeScope
    /// </summary>
    public interface IDbContext : IDisposable
    {
        /// <summary>
        ///获取数据库操作对象
        /// </summary>
        /// <param name="connectionStringType">数据库类型，如：LBBC、TCMIS等，建议使用枚举对数据库类型进行管理</param>
        /// <param name="dbProviderType"></param>
        /// <returns></returns>
        IDbHelper GetDbContext(string connectionStringType, DbTypeEnum dbProviderType);

        /// <summary>
        /// 开启事务
        /// </summary>
        /// <param name="connectionStringType">数据库类型，如：LBBC、TCMIS等，建议使用枚举对数据库类型进行管理</param>
        /// <param name="dbProviderType"></param>
        void BeginTrans(string connectionStringType, DbTypeEnum dbProviderType);

        /// <summary>
        /// 提交事务
        /// </summary>
        /// <param name="connectionStringType">数据库类型，如：LBBC、TCMIS等，建议使用枚举对数据库类型进行管理</param>
        /// <param name="dbProviderType"></param>
        void CommitTrans(string connectionStringType, DbTypeEnum dbProviderType);

        /// <summary>
        /// 回滚事务
        /// </summary>
        /// <param name="connectionStringType">数据库类型，如：LBBC、TCMIS等，建议使用枚举对数据库类型进行管理</param>
        /// <param name="dbProviderType"></param>
        void RollBackTrans(string connectionStringType, DbTypeEnum dbProviderType);

        /// <summary>
        /// 是否是否开启
        /// true标识事务已开启
        /// </summary>
        /// <param name="connectionStringType">数据库类型，如：LBBC、TCMIS等，建议使用枚举对数据库类型进行管理</param>
        /// <param name="dbProviderType"></param>
        /// <returns>true标识事务已开启</returns>
        bool IsTransOpen(string connectionStringType, DbTypeEnum dbProviderType);

        /// <summary>
        ///获取数据库操作对象
        /// </summary>
        /// <param name="connectionStringType">数据库类型，如：LBBC、TCMIS等，建议使用枚举对数据库类型进行管理</param>
        /// <param name="dbProviderType"></param>
        /// <param name="connectString">数据库连接串</param>
        /// <returns></returns>
        IDbHelper GetDbContext(string connectionStringType, DbTypeEnum dbProviderType, string connectString);
    }
}
